#include "GameBoardRenderer.h"

namespace TUMAR { namespace CountryRoads {

	GameBoardRenderer::GameBoardRenderer(void) : game(NULL), board(NULL), marker(NULL)
	{
		this->alpha=15;
		this->beta=0;
	}
	
	GameBoardRenderer::~GameBoardRenderer(void)
	{
	}
	
	void GameBoardRenderer::OnGameUpdated(const Game* game, const GameBoard* board, const MarkerEnvironment* marker)
	{
		this->game = game;
		this->board = board;
		this->marker = marker;
		if (this->direction==0){
			this->alpha+=1.5;
			if (this->alpha>15){
				this->direction=1;
			}
		}
		else{
			this->alpha-=1.5;
			if (this->alpha<-15){
				this->direction=0;
			}
		}
		this->beta+=3;
		this->Invalidate();
	}

	void GameBoardRenderer::Init(void)
	{
		this->textures[RoadStraight] = this->LoadTexture("roadstraight.bmp");
		this->textures[RoadCurve]    = this->LoadTexture("roadcurve.bmp");
		
		glClearDepth(1.0);

		// TODO: tune lightning
		// light parameters
		GLfloat light_pos[] = { 0.0, 0.0, 20.0, 0.0 };
		GLfloat light_amb[] = { 0.2, 0.2, 0.2, 1.0 };
		GLfloat light_dif[] = { 0.7, 0.7, 0.7, 1.0 };

		// enable lighting
		glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
	  	glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
		glLightfv(GL_LIGHT0, GL_AMBIENT,  light_amb);
		glLightfv(GL_LIGHT0, GL_DIFFUSE,  light_dif);

		// enable line smoothing
		glEnable( GL_LINE_SMOOTH );
		glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	}

	void GameBoardRenderer::Resize(int width, int height)
	{
		glViewport(0, 0, width, height);
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		gluPerspective(60, (float) width / (float) height, 0.01, 100.0);
	}

	void GameBoardRenderer::Render(void)
	{
		if(this->game == NULL || this->board == NULL || this->marker == NULL || !this->marker->IsBoardVisible())
			return;

		glEnable(GL_DEPTH_TEST);
		glEnable(GL_COLOR_MATERIAL);
		glEnable(GL_LIGHT0);
		glEnable(GL_LIGHTING);
					
		glMatrixMode(GL_MODELVIEW);
		glPushMatrix();
		{
			glLoadIdentity();
			glMultTransposedMatrix(this->marker->GetBoardPositionMarker()->Pose);

			this->DrawCoordFrame();
			/*
			glColor3f(0, 1, 1);
			// visualize x/y component and direction vector
			glBegin(GL_LINES);
			
				glVertex3f(0, 0, 0);
				glVertex3f(this->marker->dx, 0, 0);
				glVertex3f(0, 0, 0);
				glVertex3f(0, this->marker->dy, 0);
				glVertex3f(0, 0, 0);
				glVertex3f(0, 0, this->marker->dz);
				glVertex3f(0, 0, 0);
				glVertex3f(this->marker->dx, this->marker->dy, this->marker->dz);
				
				glColor3f(1, 1, 0);
				glVertex3f(0, 0, 0);

				const Marker* p = this->marker->GetBoardPositionMarker();
				double x = p->Pose[0] * p->Pose[3] + p->Pose[4] * p->Pose[7] + p->Pose[8] *  p->Pose[11];
				double y = p->Pose[1] * p->Pose[3] + p->Pose[5] * p->Pose[7] + p->Pose[9] *  p->Pose[11];
				double z = p->Pose[2] * p->Pose[3] + p->Pose[6] * p->Pose[7] + p->Pose[10] * p->Pose[11];


				//std::cout <<"- "<< x << " " << y << " " << z << std::endl;
				glVertex3f(p->Pose[8], p->Pose[9], p->Pose[10]);
				
			glEnd();
			*/
			double scaling = this->marker->GetBoardScale();
			glScaled(scaling, scaling, scaling);
			glRotatef(180, 1, 0, 0);
			
			this->DrawBorder();

			glPushMatrix();
			{
				for(int y = 0; y < this->board->GetHeight(); y++)
				{
					glPushMatrix();
					{
						for(int x = 0; x < this->board->GetWidth(); x++)
						{
							const Tile* tile = this->board->GetTile(x, y);
							TileType type = tile->GetType();
							
							if(type != Border)
							{
								glPushMatrix();
								{
									glRotatef(90 * tile->Orientation, 0, 0, 1);
									
									this->DrawTile(type);

									if(type == ObstacleStone)
									{
										this->DrawObstacleStone();
									}

									if(type == ObstacleHayBail)
									{
										this->DrawObstacleHayBail();
									}

									if(this->game->State == Won && tile == this->board->EndTile)
									{
										this->DrawTrophy();
									}
								}
								glPopMatrix();
							}
							glTranslatef(1.0, 0, 0);
						}
					}
					glPopMatrix();
					glTranslatef(0, 1.0, 0);
				}
			}
			glPopMatrix();

			this->DrawUserTiles();
			this->DrawCharacter();
		}
		glPopMatrix();
		
		this->DrawOutOfBorderMarkers();

		glDisable(GL_DEPTH_TEST);
		glDisable(GL_LIGHTING);
		glDisable(GL_COLOR_MATERIAL);
		glDisable(GL_LIGHT0);
	}

	void GameBoardRenderer::DrawTile(TileType type, bool color)
	{
		bool texture = this->textures.count(type) == 1;

		if(color)
		{
			this->SetColor(type);
		}

		if(texture)
		{
			glEnable(GL_TEXTURE_2D);
			glBindTexture(GL_TEXTURE_2D, this->textures[type]);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		}

		glBegin(this->GetVertexType(type));

		if(texture) glTexCoord2f(0.0f, 0.0f);
		glVertex3f(-0.5, -0.5, 0);
		if(texture) glTexCoord2f(1.0f, 0.0f);
		glVertex3f( 0.5, -0.5, 0);
		if(texture) glTexCoord2f(1.0f, 1.0f);
		glVertex3f( 0.5,  0.5, 0);
		if(texture) glTexCoord2f(0.0f, 1.0f);
		glVertex3f(-0.5,  0.5, 0);

		glEnd();

		if(texture)
		{
			glDisable(GL_TEXTURE_2D);
		}
	}

	void GameBoardRenderer::DrawCharacter(void)
	{
		//const Character* character=this->board->GetCharacter();
		glPushMatrix();
			glTranslatef(this->board->Character->Position[0], this->board->Character->Position[1],0);
			glPushMatrix();
				glRotatef(90*this->board->Character->Orientation,0,0,1);
				this->DrawHorse();
				glTranslatef(0,0,0.4);
				this->DrawCowboy();
			glPopMatrix();
		glPopMatrix();
	}

	//never called
	void GameBoardRenderer::DrawTrophy(void)
	{
		glPushMatrix();
			glRotatef(90,1,0,0);
			glTranslatef(0, 1.5, 0);
			glColor4f(0.83, 0.69, 0.22,1);
			glutSolidTeapot(0.5);
		glPopMatrix();
	}

	void GameBoardRenderer::DrawCoordFrame(void)
	{
		glBegin(GL_LINES);
			// x axis
			glColor3f(0, 1, 0);
			glVertex3f(0, 0, 0);
			glVertex3f(1, 0, 0);

			// y axis
			glColor3f(1, 1, 1);
			glVertex3f(0, 0, 0);
			glVertex3f(0, 1, 0);

			// z axis
			glColor3f(0, 0, 1);
			glVertex3f(0, 0, 0);
			glVertex3f(0, 0, 1);
		glEnd();
	}

	void GameBoardRenderer::DrawUserTiles(void)
	{
		for(std::vector<UserTile>::const_iterator it = this->board->UserTiles.begin(); it != this->board->UserTiles.end(); it++) 
		{
			glPushMatrix();
			{
				glTranslatef(it->Position[0], it->Position[1], 0.1);
				glRotatef(90 * it->Orientation, 0, 0, 1);

				if(it->Conflict)
				{
					glColor3f(1, 0, 0);
				}

				this->DrawTile(it->GetType(), !it->Conflict);
			}
			glPopMatrix();
		}
	}

	void GameBoardRenderer::DrawOutOfBorderMarkers(void)
	{
		const std::vector<const Marker*> markers = this->marker->GetOutOfBoardMarkers();

		for(int idx = 0; idx < markers.size(); idx++)
		{
			glPushMatrix();
			{
				glLoadIdentity();
				glMultTransposedMatrix(markers[idx]->Pose);
				
				TileType type = this->marker->GetTileType(markers[idx]);
				
				this->DrawTile(type);
			}
			glPopMatrix();
		}
	}

	void GameBoardRenderer::DrawBorder(void)
	{
		glLineWidth(2.0);

		glBegin(GL_LINE_LOOP);

		glColor3f(0, 0, 1);
		glVertex3f(0.5, 0.5, 0.01);
		glVertex3f(this->board->GetWidth() - 1.5, 0.5, 0.01);
		glVertex3f(this->board->GetWidth() - 1.5, this->board->GetHeight() - 1.5, 0.01);
		glVertex3f(0.5, this->board->GetHeight() - 1.5, 0.01);

		glEnd();

		glLineWidth(1.0);
	}

	//never called
	void GameBoardRenderer::DrawBomb(void){
		glColor4f(0,0,0,1);
		glRotatef(-45,0,1,0);
		glPushMatrix();
			glTranslatef(0,0,0.1);
			glutSolidSphere(0.4,30,30);
			GLUquadricObj* cyl;
			cyl = gluNewQuadric();
			glTranslatef(0,0,-0.45);
			gluCylinder(cyl, 0.2,0.2,0.2,30,30);
			gluDisk(cyl,0.0,0.2,30,30);
			glRotatef(beta,0,0,1);
			glPushMatrix();
				glLineWidth(4);
				glScalef(1,1,2.5);
				glBegin(GL_LINE_STRIP);
					glVertex3f(0, 0, 0);
					glVertex3f(0,0,-0.01);
					glVertex3f(0.025, 0.015, -0.025);
					glVertex3f(0.04,0.025,-0.04);
					glVertex3f(0.06, 0.03, -0.055);
					glVertex3f(0.04,0.025,-0.07);
					glVertex3f(0.025,0.015,-0.085);
					glVertex3f(0,0,-0.1);
				glEnd();
			glPopMatrix();
		glPopMatrix();
	}

	//never called
	void GameBoardRenderer::DrawObstacleTreeRoots(void){
		glPushMatrix();
			glRotatef(90,1,0,0);
			glTranslatef(0.0,1.1,0.0);
			glColor4f(0.45,0.2,0.2,1);
			GLUquadricObj* cyl;
			cyl = gluNewQuadric();
			glPushMatrix();
				glPushMatrix();
				glTranslatef(0,0,1.2);
				gluCylinder(cyl,0.3,0.35,0.4,30,30);
				gluDisk(cyl, 0,0.3,30,30);
			glPopMatrix();
		glPopMatrix();
	}

	//never called
	void GameBoardRenderer::DrawObstacleTreeTrunk(bool upright){
		glPushMatrix();
			glRotatef(90,1,0,0);
			glTranslatef(0.0,1.1,0.0);
			glColor4f(0.45,0.2,0.2,1);
			GLUquadricObj* cyl;
			cyl = gluNewQuadric();
			glTranslatef(0,0.29,1.2);
			if(upright){
				glRotatef(105,1,0,0);
			}
			glPushMatrix();
				glTranslatef(0,-0.29,-1.2);
				glPushMatrix();
					glTranslatef(0,0,1.2);
					gluDisk(cyl, 0,0.3,30,30);
				glPopMatrix();
				gluCylinder(cyl, 0.15,0.30,1.2,30,30);
				glColor4f(0.2,1,0.2,1);
				glutSolidSphere(0.48,14,14);
				glTranslatef(0.5,0,0.7);
				glRotatef(-50,0,1,0);
				glPushMatrix();
					glColor4f(0.45,0.2,0.2,1);
					gluCylinder(cyl, 0.08,0.2,0.6,30,30);
					glColor4f(0.2,1,0.2,1);
					glTranslatef(0.12,0,-0.06);
					glutSolidSphere(0.2,10,10);
					glTranslatef(-0.24,0,0);
					glutSolidSphere(0.2,10,10);
					glTranslatef(0.12,0.15,0);
					glutSolidSphere(0.2,10,10);
					glTranslatef(0,-0.24,0);
					glutSolidSphere(0.2,10,10);
					glTranslatef(0,0.12,-0.17);
					glutSolidSphere(0.2,10,10);
				glPopMatrix();
			glPopMatrix();
		glPopMatrix();
	}

	void GameBoardRenderer::DrawObstacleStone(void){
		glPushMatrix();
			glRotatef(90,0,0,1);
			//glTranslatef(0.0,0.5,0.0);
			glPushMatrix();
				glRotatef(90,1,0,0);
				glTranslatef(0.0,0.5,0.0);
				glPushMatrix();
					glTranslatef(0.1,-0.2,0.0);
					glColor4f(0.45,0.4,0.35,1.0);
					glScalef(0.7,1.0,1.1);
					glutSolidSphere(0.4,10,12);
				glPopMatrix();
				glPushMatrix();
					glTranslatef(0.0,-0.3,0.0);
					glColor4f(0.35,0.4,0.3,1.0);
					glScalef(1.2,0.8,0.7);
					glutSolidSphere(0.3,10,10);
				glPopMatrix();
				glPushMatrix();
					glTranslatef(-0.2,-0.4,0.2);
					glColor4f(0.25,0.3,0.35,1.0);
					glScalef(0.9,0.8,0.85);
					glutSolidSphere(0.2,10,8);
				glPopMatrix();
				glPushMatrix();
					glColor4f(0.35,0.3,0.35,1.0);
					glTranslatef(-0.35,-0.4,-0.4);
					glutSolidSphere(0.15,10,8);
					glTranslatef(0.7,0.0,0.0);
					glutSolidSphere(0.095,10,8);
					glTranslatef(0.0,0.0,0.8);
					glutSolidSphere(0.11,10,8);
				glPopMatrix();
			glPopMatrix();
		glPopMatrix();
	}

	void GameBoardRenderer::DrawObstacleHayBail(void){
		glPushMatrix();
			//center bail on tile
			glRotatef(90,1,0,0);
			glTranslatef(0.0,0.5,0.0);
			glTranslatef(0,-0.1,-0.25);
			GLUquadricObj* cyl;
			cyl = gluNewQuadric();
			gluQuadricDrawStyle(cyl, GLU_FILL);
			//disks designing the front of the bail
			glColor4f(0.8,0.7,0.4,1.0);
			gluDisk(cyl, 0.0f, 0.05, 18, 1);
			gluDisk(cyl, 0.1f, 0.15, 36, 1);
			gluDisk(cyl, 0.2f, 0.25, 12, 1);
			gluDisk(cyl, 0.3f, 0.35, 24, 3);
					
			glColor4f(0.8,0.55,0.3,1.0);
			gluDisk(cyl, 0.05f, 0.1, 12, 1);
			gluDisk(cyl, 0.15f, 0.2, 20, 1);
			gluDisk(cyl, 0.25f, 0.3, 32, 1);
			gluDisk(cyl, 0.35f, 0.4, 48, 1);
			//the torso
			gluCylinder(cyl, 0.4, 0.4, 0.1, 12, 12);
			glColor4f(0.8,0.7,0.4,1.0);
			glTranslatef(0,0,0.1);
			gluCylinder(cyl, 0.4, 0.4, 0.1, 12, 12);
			glColor4f(0.8,0.55,0.3,1.0);
			glTranslatef(0,0,0.1);
			gluCylinder(cyl, 0.4, 0.4, 0.1, 12, 12);
			glColor4f(0.8,0.7,0.4,1.0);
			glTranslatef(0,0,0.1);
			gluCylinder(cyl, 0.4, 0.4, 0.1, 12, 12);
			glColor4f(0.8,0.55,0.3,1.0);
			glTranslatef(0,0,0.1);
			gluCylinder(cyl, 0.4, 0.4, 0.1, 12, 12);
			//the backside
			glColor4f(0.8,0.7,0.4,1.0);
			glTranslatef(0,0,0.1);
			gluDisk(cyl, 0.0f, 0.05, 12, 1);
			gluDisk(cyl, 0.1f, 0.15, 20, 1);
			gluDisk(cyl, 0.2f, 0.25, 36, 1);
			gluDisk(cyl, 0.3f, 0.35, 24, 3);
		
			glColor4f(0.8,0.55,0.3,1.0);
			gluDisk(cyl, 0.05f, 0.1, 36, 1);
			gluDisk(cyl, 0.15f, 0.2, 12, 1);
			gluDisk(cyl, 0.25f, 0.3, 38, 1);
			gluDisk(cyl, 0.35f, 0.4, 30, 1);
		glPopMatrix();
	}

	void GameBoardRenderer::DrawHorse(void){
		//initial direction: going to the left side of the screen
		//rotate arount y-Axis for change of direction
		//initial position: rectangle 0|0, 0|1, 1|1, 1|0
		glPushMatrix();
			glRotatef(90,0,0,1);
			glRotatef(90,1,0,0);
			glTranslatef(0.0,0.5,-0.2);
			//initialization of cylinder parameters
			glTranslatef(0.08, -0.1, 0.0);
			GLUquadricObj* cyl;
			cyl = gluNewQuadric();
			gluQuadricDrawStyle(cyl, GLU_FILL);
			//define body center and color
			glColor4f(0.5, 0.4, 0.3, 1.0);
			//neck
			glPushMatrix();
				glTranslatef(-0.2,0,0);
				glRotatef(-90, 1,0,0);
				glRotatef(-20,0,1,0);
				gluCylinder(cyl, 0.09, 0.04, 0.3, 12, 12);
			glPopMatrix();
			//ears
			glPushMatrix();
				glRotatef(-90, 1,0,0);
				glTranslatef(-0.3,0.0,0.3);
				glRotatef(15, 0,1,0);
				glPushMatrix();
					glRotatef(-30, 1,0,0);
					glutSolidCone(0.04, 0.15, 10,10);
				glPopMatrix();
				glPushMatrix();
					glRotatef(30, 1,0,0);
					glutSolidCone(0.04, 0.15, 10,10);
				glPopMatrix();
			glPopMatrix();
			//body and head
			glPushMatrix();
				glScalef(1.2, 0.5, 0.5);
				glutSolidSphere(0.3, 25,25);
				glTranslatef(-0.29, 0.5,0.0);
				glScalef(0.9, 1.1, 1.1);
				glutSolidSphere(0.12, 25,25);
			glPopMatrix();	
			//legs right
			glPushMatrix();
				glRotatef(90,1,0,0);
				glPushMatrix();
					glTranslatef(-0.235,0.09,0.05);
					glPushMatrix();
						glRotatef(alpha,0,1,0);
						glutSolidSphere(0.06, 12,12);
						gluCylinder(cyl, 0.06, 0.03, 0.35, 12, 12);
					glPopMatrix();
					glTranslatef(0.48,0,0);
					glPushMatrix();
						glRotatef(alpha,0,1,0);
						glutSolidSphere(0.06, 12,12);
						gluCylinder(cyl, 0.06, 0.03, 0.35, 12, 12);
					glPopMatrix();
				glPopMatrix();
			glPopMatrix();
			//legs left
			glPushMatrix();
				glRotatef(90,1,0,0);
				glPushMatrix();
					glTranslatef(-0.235,-0.09,0.05);
					glPushMatrix();
						glRotatef(-alpha,0,1,0);
						glutSolidSphere(0.06, 12,12);
						gluCylinder(cyl, 0.06, 0.03, 0.35, 12, 12);
					glPopMatrix();
					glTranslatef(0.48,0,0);
					glPushMatrix();
						glRotatef(-alpha,0,1,0);
						glutSolidSphere(0.06, 12,12);
						gluCylinder(cyl, 0.06, 0.03, 0.35, 12, 12);
					glPopMatrix();
				glPopMatrix();
			glPopMatrix();
			//tail
			glColor4f(0.2,0,0,1);
			glPushMatrix();
				glRotatef(90,1,0,0);
				glPushMatrix();
					glTranslatef(0.36,0,-0.02);
					glPushMatrix();
						glRotatef(alpha*0.5,1,0,0);
						glRotatef(alpha*0.3,0,1,0);
						glutSolidSphere(0.03, 12,12);
						gluCylinder(cyl, 0.03, 0.005, 0.35, 12, 12);
					glPopMatrix();
				glPopMatrix();
			glPopMatrix();
			//eyes
			glColor4f(0,0,0,1);
			glPushMatrix();
				glRotatef(90,1,0,0);
				glTranslatef(-0.365, 0.03, -0.31);
				glutSolidSphere(0.01,12,12);
				glTranslatef(0, -0.06, 0);
				glutSolidSphere(0.01,12,12);
			glPopMatrix();
	glPopMatrix();
	
	}

	void GameBoardRenderer::DrawCowboy(void)
	{
		glRotatef(180,1,0,0);
		glTranslatef(0.0,0,-0.58);
		glPushMatrix();
		glScalef(0.8,0.8,0.8);
		//glTranslatef(0,0,-0.2);
		GLUquadricObj* cyl;
		cyl = gluNewQuadric();
		gluQuadricDrawStyle(cyl, GLU_FILL);
		//Head and Neck
		glPushMatrix();
			glColor4f(0.9,0.7,0.7,1);
			glTranslatef(0,0,-0.3);
			gluCylinder(cyl, 0.04, 0.04, 0.2, 12, 12);
			glTranslatef(0,0,-0.05);
			glutSolidSphere(0.115,12,12);
			glPushMatrix();
				glColor4f(1,0.6,0.6,1);
				glRotatef(90,-1,0,0);
				glScalef(1.7,1,1);
				glutSolidCone(0.04,0.17,12,12);
			glPopMatrix();
			glPushMatrix();
				glColor4f(0,0,0,1);
				glTranslatef(0.055,0.1,-0.03);
				glutSolidSphere(0.015,12,12);
				glTranslatef(-0.11,0,0);
				glutSolidSphere(0.015,12,12);
			glPopMatrix();
			glPushMatrix();
				glTranslatef(0,0.11,0.03);
				glColor4f(1,0,0,1);
				glLineWidth(2);
				glRotatef(17,1,0,0);
				glBegin(GL_LINE_LOOP);
					glVertex3f(-0.05, 0, 0);
					glVertex3f(-0.025, 0, 0.025);
					glVertex3f(0,0,0.03);
					glVertex3f(0.025, 0, 0.025);
					glVertex3f(0.05,0,0);
					glVertex3f(0,0,0.01);
				glEnd();
			glPopMatrix();
		glPopMatrix();
		glColor4f(0,0,0,1);
		//hat
		glPushMatrix();
			glTranslatef(0,0,-0.42);
			glRotatef(10,-1,1,0);
			gluDisk(cyl, 0.0f, 0.25, 12, 1);
			glTranslatef(0,0,-0.02);
			gluCylinder(cyl, 0.25, 0.25, 0.02, 12, 12);
			glTranslatef(0,0,-0.08);
			gluCylinder(cyl, 0.15, 0.15, 0.1, 12, 12);
			gluDisk(cyl, 0.0f, 0.15, 12, 1);
		glPopMatrix();
		glColor4f(0.8,0.2,0.2,1.0);
		//Torso
		glPushMatrix();
			glScalef(0.9,0.5,1.5);
			glutSolidSphere(0.15,12,12);
		glPopMatrix();
		//arms
		glPushMatrix();
			glTranslatef(0,0,-0.2);
			//right
			glPushMatrix();
				glRotatef(-alpha*0.9-10,1,0,0);
				glPushMatrix();
					glRotatef(50, 0,1,0);
					glRotatef(10,1,0,0);
					gluCylinder(cyl, 0.035, 0.035, 0.31, 12, 12);
				glPopMatrix();
				glTranslatef(0.22,-0.05,0.2);
				glutSolidSphere(0.038,12,12);
				gluCylinder(cyl, 0.035, 0.035, 0.23, 12, 12);
				glTranslatef(0,0,0.25);
				glColor4f(0.9,0.7,0.7,1);
				glutSolidSphere(0.035,12,12);
			glPopMatrix();
			//left
			glColor4f(0.8,0.2,0.2,1.0);
			glPushMatrix();
				glRotatef(alpha*0.9-10,1,0,0);
				glPushMatrix();
					glRotatef(-50,0,1,0);
					glRotatef(10,1,0,0);
					gluCylinder(cyl, 0.035, 0.035, 0.31, 12, 12);
				glPopMatrix();
				glTranslatef(-0.22,-0.05,0.2);
				glutSolidSphere(0.038,12,12);
				gluCylinder(cyl, 0.035, 0.035, 0.23, 12, 12);
				glTranslatef(0,0,0.25);
				glColor4f(0.9,0.7,0.7,1);
				glutSolidSphere(0.035,12,12);
			glPopMatrix();
		glPopMatrix();
		//legs
		//right
		glPushMatrix();
			glColor4f(0.4,0.2,0.2,1.0);
			glRotatef(alpha*0.8,1,0,0);
			glPushMatrix();
				glTranslatef(0,0,0.1);
				glPushMatrix();
					glRotatef(40, 0,1,0);
					glRotatef(-10,1,0,0);
					gluCylinder(cyl, 0.045, 0.045, 0.25, 12, 12);
				glPopMatrix();
				glTranslatef(0.15,0.05,0.2);
				glutSolidSphere(0.05,12,12);
				gluCylinder(cyl, 0.045, 0.055, 0.28, 12, 12);
				glTranslatef(0,0.05,0.3);
				glScalef(0.8,2,0.5);
				glColor4f(0,0,0,1.0);
				glutSolidSphere(0.06,12,12);
			glPopMatrix();
		glPopMatrix();
		//left
		glPushMatrix();
			glColor4f(0.4,0.2,0.2,1.0);
			glRotatef(-alpha*0.8,1,0,0);
			glPushMatrix();
				glTranslatef(0,0,0.1);
				glPushMatrix();
					glRotatef(-40, 0,1,0);
					glRotatef(-10,1,0,0);
					gluCylinder(cyl, 0.045, 0.045, 0.25, 12, 12);
				glPopMatrix();
				glTranslatef(-0.15,0.05,0.2);
				glutSolidSphere(0.05,12,12);
				gluCylinder(cyl, 0.045, 0.055, 0.28, 12, 12);
				glTranslatef(0,0.05,0.3);
				glScalef(0.8,2,0.5);
				glColor4f(0,0,0,1.0);
				glutSolidSphere(0.06,12,12);
			glPopMatrix();
		glPopMatrix();
	glPopMatrix();
}
	
	void GameBoardRenderer::SetColor(TileType type)
	{
		switch(type)
		{
		case ObstacleStone:
		case ObstacleHayBail:
		case ObstacleTree:
			glColor3f(0.5, 0.5, 0.5);
			break;
		case Border:
			glColor3f(0.0, 0.0, 1.0);
			break;
		case RoadStraight:
		case RoadCurve:
			glColor3f(1.0, 1.0, 1.0);
			break;
		default:
			glColor3f(1.0, 0.0, 0.0);
			break;
		}
	}

	GLenum GameBoardRenderer::GetVertexType(TileType type)
	{
		switch(type)
		{
		case Empty:
			return GL_LINE_LOOP;
		default:
			return GL_QUADS;
		}
	}
}}